/*
 * Copyright (C) 2012 Sony Computer Entertainment Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "AboutData.h"

#include "MemoryCache.h"
#include "TextEncoding.h"
#include <wtf/text/Base64.h>

#if OS(PSP2)
extern "C" size_t malloc_max_inuse_size();
extern "C" size_t malloc_current_inuse_size();
#endif

using namespace WebCore;

static String htmlHeader(const KURL& aboutUrl);
static String htmlBody(const KURL& aboutUrl);

static String aboutManxBody();
static String aboutMemoryBody();

static String css();

static const char* compassData();

KURL createAboudDataUri(const KURL& aboutUrl)
{
    if (aboutUrl.path() == "blank")
        return WebCore::KURL();
    
    if (aboutUrl.path() == "compass") {
        String url = "data:text/html;charset=utf-8;base64,";    
        url.append(compassData());
        return KURL(KURL(), url, UTF8Encoding());
    }

    String html;
    html.append("<html><head>");
    html.append(htmlHeader(aboutUrl));
    html.append("<head/><body>");
    html.append(htmlBody(aboutUrl));
    html.append("</body></html>");

    String url = "data:text/html;charset=utf-8;base64,";    
    url.append(base64Encode(html.ascii(), Base64DoNotInsertLFs));
    return KURL(KURL(), url, UTF8Encoding());
}

static String htmlHeader(const KURL& aboutUrl)
{
    String header;
    header.append("<title>About</title>");
    header.append(css());
    return header;
}

static String htmlBody(const KURL& aboutUrl)
{
    if (aboutUrl.path() == "memory")
        return aboutMemoryBody();

    return aboutManxBody();
}

static String aboutManxBody()
{
    String body = "";
    return body;
}

static String mallocStatisticsTable()
{
    size_t max = 0;
    size_t current = 0;
#if OS(PSP2)
    max = malloc_max_inuse_size();
    current = malloc_current_inuse_size();
#endif
    
    String table = "<table><tr><th>maxInUse</th><th>currentInUse</th></tr>";
    table.append("<tr><td>" + String::number(max) + "</td>");
    table.append("<td>" + String::number(current) + "</td></tr></table>");
    return table;
}

static String memoryCacheStatisticsHeader()
{
    String row;
    row.append("<tr>");
    row.append("<th></th>");
    row.append("<th>count</th>");
    row.append("<th>size</th>");
    row.append("<th>liveSize</th>");
    row.append("<th>decodedSize</th>");
    row.append("<th>purgeableSize</th>");
    row.append("<th>purgedSize</th>");
    row.append("</tr>");
    return row;
}

static String memoryCacheStatisticsRow(const MemoryCache::TypeStatistic& statistic, const String& description)
{
    String row;
    row.append("<tr>");
    row.append("<td>" + description + "</td>");
    row.append("<td>" + String::number(statistic.count) + "</td>");
    row.append("<td>" + String::number(statistic.size) + "</td>");
    row.append("<td>" + String::number(statistic.liveSize) + "</td>");
    row.append("<td>" + String::number(statistic.decodedSize) + "</td>");
    row.append("<td>" + String::number(statistic.purgeableSize) + "</td>");
    row.append("<td>" + String::number(statistic.purgedSize) + "</td>");
    row.append("</tr>");
    return row;
}

#define ADD_MEMORY_STATISTICS_ROW(x) body.append(memoryCacheStatisticsRow(statistic.x, #x));
static String aboutMemoryBody()
{
    String body;

    // FastMalloc
    body.append("<h3>malloc</h3>");
    body.append(mallocStatisticsTable());

    // MemoryCache
    body.append("<h3>MemoryCache</h3>");
    body.append("<table>");
    body.append(memoryCacheStatisticsHeader());
    MemoryCache::Statistics statistic = memoryCache()->getStatistics();
    ADD_MEMORY_STATISTICS_ROW(images);
    ADD_MEMORY_STATISTICS_ROW(cssStyleSheets);
    ADD_MEMORY_STATISTICS_ROW(scripts);
    ADD_MEMORY_STATISTICS_ROW(xslStyleSheets);
    ADD_MEMORY_STATISTICS_ROW(fonts);
    body.append("</table>");
    return body;
}

static String css()
{
    String css;
    css.append("<style type=\"text/css\">");
    css.append("* { font-family: sans-serif }");
    css.append("table { border: 1px White solid); border-collapse: collapse); }");
    css.append("tr:nth-child(odd) { background-color:WhiteSmoke }");
    css.append("tr:nth-child(even) { background-color:White }");
    css.append("th { background-color:Gainsboro }");
    css.append("td { text-align:right; width:20em; padding:2px }");
    css.append("</style>");
    return css;
}


static const char* compassData()
{
    return 
        "PGh0bWw+PGhlYWQ+PG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13"
        "aWR0aCxpbml0aWFsLXNjYWxlPTEuMCx1c2VyLXNjYWxhYmxlPW5vOyI+PC9oZWFkPjxib2R5IHN0"
        "eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOmJsYWNrIj48ZGl2IHN0eWxlPSJ3aWR0aDoxMjg7dG9wOjUw"
        "JTtsZWZ0OjUwJTstd2Via2l0LXRyYW5zZm9ybTp0cmFuc2xhdGUoLTY0cHgsLTY0cHgpO3Bvc2l0"
        "aW9uOnJlbGF0aXZlIj48Y2FudmFzIGlkPSJiIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCIgc3R5"
        "bGU9InBvc2l0aW9uOmFic29sdXRlOyI+PC9jYW52YXM+PGNhbnZhcyBpZD0ibyIgd2lkdGg9IjE2"
        "IiBoZWlnaHQ9IjE2IiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7Ij48L2NhbnZhcz48Y2FudmFz"
        "IGlkPSJnIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHN0eWxlPSJwb3NpdGlvbjphYnNvbHV0ZTsi"
        "PjwvY2FudmFzPjwvZGl2PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij52YXIgY29sb3I9"
        "J3JnYmEoNSwgMTg1LCA1LCAwLjcpJzt2YXIgY29udGV4dCA9IGRvY3VtZW50LmdldEVsZW1lbnRC"
        "eUlkKCdiJykuZ2V0Q29udGV4dCgnMmQnKTtjb250ZXh0LnN0cm9rZVN0eWxlPWNvbG9yO2NvbnRl"
        "eHQubGluZVdpZHRoID0gMjtjb250ZXh0LmJlZ2luUGF0aCgpO2NvbnRleHQuYXJjKDY0LCA2NCwg"
        "NjMsIDAsIDIgKiBNYXRoLlBJLCBmYWxzZSk7Y29udGV4dC5zdHJva2UoKTtjb250ZXh0ID0gZG9j"
        "dW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ28nKS5nZXRDb250ZXh0KCcyZCcpO2NvbnRleHQuZmlsbFN0"
        "eWxlPWNvbG9yO2NvbnRleHQuYmVnaW5QYXRoKCk7Y29udGV4dC5hcmMoOCwgOCwgNywgMCwgMiAq"
        "IE1hdGguUEksIGZhbHNlKTtjb250ZXh0LmZpbGwoKTtjb250ZXh0ID0gZG9jdW1lbnQuZ2V0RWxl"
        "bWVudEJ5SWQoJ2cnKS5nZXRDb250ZXh0KCcyZCcpO2NvbnRleHQuZmlsbFN0eWxlPWNvbG9yO2Nv"
        "bnRleHQuYmVnaW5QYXRoKCk7Y29udGV4dC5hcmMoOCwgOCwgNywgMCwgMiAqIE1hdGguUEksIGZh"
        "bHNlKTtjb250ZXh0LmZpbGwoKTs8L3NjcmlwdD48c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlw"
        "dCI+YWRkRXZlbnRMaXN0ZW5lcigiZGV2aWNlb3JpZW50YXRpb24iLCBmdW5jdGlvbihldmVudCkg"
        "e3ZhciBjID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm8iKTtjLnN0eWxlLmxlZnQgPSA1OCs1"
        "OCAqIE1hdGguc2luKGV2ZW50LmFscGhhKk1hdGguUEkvMTgwKTtjLnN0eWxlLnRvcCA9IDU4LTU4"
        "ICogTWF0aC5jb3MoZXZlbnQuYWxwaGEqTWF0aC5QSS8xODApO3ZhciBkID0gZG9jdW1lbnQuZ2V0"
        "RWxlbWVudEJ5SWQoImciKTtkLnN0eWxlLmxlZnQgPSA2NCsyICogZXZlbnQuZ2FtbWE7ZC5zdHls"
        "ZS50b3AgPSA2NCsyICogZXZlbnQuYmV0YTt9LCB0cnVlKTs8L3NjcmlwdD48L2JvZHk+PC9odG1s"
        "Pg==";
}
